/*
 * Copyright 2013 Brandon O'Toole
 * 
 * This file is part of EdgeSleuth.
 * 
 * EdgeSleuth is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * EdgeSleuth is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with EdgeSleuth.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.IndieRayDev.EdgeSleuth;

import com.IndieRayDev.EdgeSleuth.EdgeDetector;
import com.IndieRayDev.EdgeSleuth.DrawImage.ImageThread;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.OutputStream;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.CheckBox;

public class MainActivity extends Activity {
	
	private DrawImage mImageDraw;
	//private ImageThread mImageThread;
    private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
	private static final int SELECT_PICTURE = 200;
	private Uri picCapUri;
	
	boolean setBackground = false;
	boolean hasImage = false;
	int intColor = 0;

	CheckBox runFilter;
	Uri lowResUri;
	Button button;
	Context someContext;
	AttributeSet someAttributes;
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.activity_main, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	        case R.id.settings:
                Intent settingsIntent = new Intent(this, SettingsActivity.class);
	        	startActivity(settingsIntent);
	            return true;
	        case R.id.getImage:
	        	useNewImage();
	            return true;
	        case R.id.captureImage:
	            dispatchTakePictureIntent(1);
	            return true;
	        case R.id.goFilter:
	        	if (hasImage){
	        		processFilter();
	        	}
	        default:
	            return super.onOptionsItemSelected(item);
	    }
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main_draw_image);

	    // First decode with inJustDecodeBounds=true to check dimensions
	    final BitmapFactory.Options options = new BitmapFactory.Options();
	    options.inJustDecodeBounds = true;
	    
	    // options.inSampleSize = 1;
	    options.inScaled = false;
	    options.inTargetDensity = 0;
	    
	    // Decode bitmap with inSampleSize set
	    options.inJustDecodeBounds = false;
		Bitmap initialBg = BitmapFactory.decodeResource(getResources(), R.drawable.tree, options);
		EdgeDetector edgeImages = new EdgeDetector(initialBg);
		Bitmap edgeBg = Bitmap.createBitmap(edgeImages.getEdgeStrenths());
		setupCanvas(initialBg, edgeBg);
		
		initialBg.recycle();
		initialBg = null;
		edgeBg.recycle();
		edgeBg = null;
		
		this.setTitle("EdgeSleuth Main Screen");	
	}
	
	@Override
	protected final void onActivityResult(int requestCode, int resultCode, Intent data){
		if(resultCode == RESULT_OK){
			if(requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE){
				handleImageCapture();
			} else if(requestCode == SELECT_PICTURE){
	            handleImageSelect(data);
			} else if(requestCode == 11212){
				handleImageFilter();
			} else{
				setBackground = false;
				hasImage = false;
			}
		}else{
			setBackground = false;
			hasImage = false;
		}
	}
	
	private void setupCanvas(Bitmap topImage, Bitmap botImage){
        if(mImageDraw == null){
    		mImageDraw = (DrawImage) findViewById(R.id.bg_tree);
            mImageDraw.setScreenSize(this);
            //mImageThread = mImageDraw.getThread();
    		mImageDraw.setOnTouchListener(new OnTouchListener(){
    			@Override
    			public boolean onTouch(View v, MotionEvent event) {
    				((DrawImage)v).addAlphaToSet(event.getX(), event.getY());
    				return true;
    			}
    		});
        }
        mImageDraw.setBitmaps(topImage, botImage);
	}
	
	private void handleImageCapture(){
		String picCapPath;
		setBackground = true;
		picCapPath = picCapUri.getPath();
		
	    // First decode with inJustDecodeBounds=true to check dimensions
	    final BitmapFactory.Options options = new BitmapFactory.Options();
	    options.inJustDecodeBounds = true;
	    Bitmap topImage = BitmapFactory.decodeFile(picCapPath, options);
	    
	    // Calculate inSampleSize
	    options.inSampleSize = calculateInSampleSize(options);
	    
	    options.inJustDecodeBounds = false;
	    topImage = BitmapFactory.decodeFile(picCapPath, options);
	    EdgeDetector edgeImages = new EdgeDetector(topImage);
		Bitmap botImage = Bitmap.createBitmap(edgeImages.getEdgeStrenths());
		setupCanvas(topImage, botImage);
		
		topImage.recycle();
		topImage = null;
		botImage.recycle();
		botImage = null;
		
		setBackground = true;
		hasImage = true;		
	}
	
	private void handleImageSelect(Intent data){
		Uri picCapUri = data.getData();
		Uri selectedImageUri = data.getData();
		String picCapPath = getPath(selectedImageUri);
        
	    // First decode with inJustDecodeBounds=true to check dimensions
	    final BitmapFactory.Options options = new BitmapFactory.Options();
	    options.inJustDecodeBounds = true;
	    Bitmap topImage = BitmapFactory.decodeFile(picCapPath, options);
	    
	    // Calculate inSampleSize
	    options.inSampleSize = calculateInSampleSize(options);

	    // Decode bitmap with inSampleSize set
	    options.inJustDecodeBounds = false;
	    topImage = BitmapFactory.decodeFile(picCapPath, options);
	    
	    options.inJustDecodeBounds = false;
		EdgeDetector edgeImages = new EdgeDetector(topImage);
		Bitmap botImage = Bitmap.createBitmap(edgeImages.getEdgeStrenths());
		setupCanvas(topImage, botImage);
		
		topImage.recycle();
		topImage = null;
		botImage.recycle();
		botImage = null;
		
		setBackground = true;
		hasImage = true;
	}
	
	private void handleImageFilter(){
		setBackground = true;
		try{
			//filteredBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), lowResUri);
			//edgeImages = new EdgeDetector(filteredBitmap);
		} catch( Exception e) {
		}
	}
	
	public static final int MEDIA_TYPE_IMAGE = 1;
	public static final int MEDIA_TYPE_VIDEO = 2;
	
	public void useNewImage(){
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent,
                "Select Picture"), SELECT_PICTURE);
	}
	
	private void dispatchTakePictureIntent(int actionCode) { 
		Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		
		picCapUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
		takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, picCapUri); // set the image file name
		
		// start the image capture Intent
		startActivityForResult(takePictureIntent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
	}

	/** Create a file Uri for saving an image or video */
	private static Uri getOutputMediaFileUri(int type){
	      return Uri.fromFile(getOutputMediaFile(type));
	}
	
	public String getPath(Uri uri) {
	    String[] projection = { MediaStore.Images.Media.DATA };
	    Cursor cursor = managedQuery(uri, projection, null, null, null);
	    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
	    cursor.moveToFirst();
	    return cursor.getString(column_index);
	}
	
	private int calculateInSampleSize( BitmapFactory.Options options ) {
		float ratio;
		
		// TODO make this play nice with all screen sizes?
		ratio = options.outWidth/800;
		
		if(ratio <= 1){
			return 1;
		} else if(ratio <= 2){
			return 2; 
		} else if(ratio <= 4){
			return 4; 
		} else if(ratio <= 8){
			return 8;
		} else if(ratio <= 16){
			return 16;
		} else{
			return 32;
		}

	}

	/** Create a File for saving an image or video */
	private static File getOutputMediaFile(int type){
		File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "MyCameraApp");
	    if (! mediaStorageDir.exists()){
	        if (! mediaStorageDir.mkdirs()){
	            //Log.d("MyCameraApp", "failed to create directory");
	            return null;
	        }
	    }

	    // Create a media file name
	    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
	    File mediaFile;
	    if (type == MEDIA_TYPE_IMAGE){
	        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
	        "IMG_"+ timeStamp + ".jpg");
	    } else if(type == MEDIA_TYPE_VIDEO) {
	        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
	        "VID_"+ timeStamp + ".mp4");
	    } else {
	        return null;
	    }

	    return mediaFile;
	}
	
	private void processFilter(){
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
		if( prefs.getBoolean("filterCheckBox", true) ){
			
			lowResUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
			try{
				OutputStream outStream = this.getContentResolver().openOutputStream(lowResUri);
				//globalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
				outStream.flush();
				outStream.close();
			} catch( Exception e)	{
				// TODO justify an empty catch
			}

			// TODO embed the image URI and then start the activity 
			Intent filterIntent = new Intent(MainActivity.this, BilateralFilter.class);
			filterIntent.putExtra(MediaStore.EXTRA_OUTPUT, lowResUri); // set the image file name
			
			// start the image capture Intent
			startActivityForResult(filterIntent, 11212);
		} 
	}
	
}
